package com.wiringweb.parameterprocessor.implementation;

import com.gooddies.utils.IterableEnumeration;
import com.wiringweb.data.FormData;
import com.wiringweb.exceptions.WiringWebException;
import com.wiringweb.parameterprocessor.ParameterProcessorInterface;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * @author sad
 */
public class FormDataImpl extends ParameterProcessorInterface {

    public static class UploadedFile {

        private File file;
        private long size;
        private String fileName;

        public UploadedFile(File file, long size, String fileName) {
            this.file = file;
            this.size = size;
            this.fileName = fileName;
        }

        public File getFile() {
            return file;
        }

        public long getSize() {
            return size;
        }

        public String getFileName() {
            return fileName;
        }
    }

    @Override
    public Object process(HttpServletResponse response, HttpServletRequest request, String[] urlParameter, int parameterIndex) throws IOException, IllegalStateException, ServletException, FileUploadException {
        Map<String, Object> hashMap = new HashMap<String, Object>(10);
        if (ServletFileUpload.isMultipartContent(request)) {
            DiskFileUpload upload = new DiskFileUpload();
            List items = null;
            try {
                // parse this request by the handler
                // this gives us a list of items from the request
                items = upload.parseRequest(request);
            } catch (FileUploadException ex) {
                throw new WiringWebException("Error while upload file", ex);
            }

            Iterator itr = items.iterator();
            while (itr.hasNext()) {
                FileItem item = (FileItem) itr.next();
                // check if the current item is a form field or an uploaded file
                if (item.isFormField()) {
                    // get the name of the field
                    String fieldName = item.getFieldName();
                    hashMap.put(fieldName, item.getString());
                } else {
                    File fullFile = new File(item.getName());
                    File savedFile = new File(request.getServletContext().getRealPath("/"), fullFile.getName());
                    try {
                        item.write(savedFile);
                    } catch (Exception ex) {
                        throw new WiringWebException("Error while upload file", ex);
                    }
                    UploadedFile uf = new UploadedFile(savedFile, item.getSize(), item.getName());
                    hashMap.put(item.getFieldName(), uf);
                }
            }
        } else {
            for (String key : IterableEnumeration.make(request.getParameterNames())) {
                String value = request.getParameter(key);
                value = new String(value.getBytes("iso-8859-1"), "UTF-8");
                hashMap.put(key, value);
            }
        }
        FormData params = new FormData(hashMap);
        return params;
    }

    @Override
    public ParameterProcessorInterface construct(Class argumentType, Annotation annotation) {
        return new FormDataImpl();

    }
}
